package com.zen.payserver.controller;

import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradeAppPayModel;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradeAppPayRequest;
import com.alipay.api.response.AlipayTradeAppPayResponse;
import com.zen.payserver.bean.Order;
import com.zen.payserver.constant.HttpConstants;
import com.zen.payserver.constant.PayConstants;
import com.zen.payserver.util.GsonUtils;
import com.zen.payserver.util.ResponseUtils;
import com.zen.payserver.util.Result;
import com.zen.payserver.util.TempUtils;

@Controller
@ResponseBody
@RequestMapping(value = "pay")
public class PayController {
	protected static final Logger logger = LoggerFactory
			.getLogger(PayController.class);

	@RequestMapping("/hello")
	public String hello() {
		logger.debug("hello1 debug");
		logger.info("hello1 info");
		logger.error("hello1 error");
		return "Hello1 Spring Boot!";
	}

	/**
	 * 支付通用接口
	 * 
	 * @param HowToPay
	 * @param orderId
	 * @param forWhat
	 * @param payMoney
	 * @param req
	 * @return
	 */
	@RequestMapping(value = "/createOrder")
	public String commonPay(HttpServletRequest req, HttpServletResponse res) {
		// 支付宝 逻辑
		Order orders = new Order();
		Result result = new Result();
		String oldPhone = "";// (String) req.getAttribute("oldPhone");

		// 充值逻辑，在此生成订单
		String time = System.currentTimeMillis() + "";
		orders.setEnd_time(time);
		String orderid = TempUtils.createOrderID();
		orders.setOrderid(orderid);
		orders.setPaymoney(new BigDecimal("0.01"));
		orders.setPhone(oldPhone);
		orders.setStart_time(time);
		orders.setStatus(PayConstants.PAY_STATUS_UNPAID);
		String logInfo = "";
		try {
			// orderService.SaveOrdersInfo(orders, 0L);
			TempUtils.saveOrder(orders);
		} catch (Exception e) {
			e.printStackTrace();
			result.setCode(HttpConstants.HTTP_RESP_FAILED);
			result.setMsg("充值订单生成失败");
			result.setData("充值订单生成失败");
			logInfo = GsonUtils.GsonString(result);
			logger.info(logInfo);
			return logInfo;

		}
		String aliPaySignPrams = aliPaySignPrams(orders);

		result.setCode(HttpConstants.HTTP_RESP_SUCCESS);
		result.setMsg("支付宝加签成功");
		result.setData(aliPaySignPrams);
		logInfo = GsonUtils.GsonString(result);
		logger.info(logInfo);
		return logInfo;

	}

	/**
	 * 加签参数
	 * 
	 * @param amount
	 * @param body
	 * @return
	 */
	public String aliPaySignPrams(Order orders) {
		// 实例化客户端
		AlipayClient alipayClient = new DefaultAlipayClient(
				PayConstants.ALIPAY_WEBWAY, PayConstants.ALIPAY_APPID,
				PayConstants.ALIPAY_PRIVATE_KEY, "json",
				PayConstants.ALIPAY_CHARSET, PayConstants.ALIPAY_PUBLIC_KEY,
				"RSA2");
		// 实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称：alipay.trade.app.pay
		AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
		// SDK已经封装掉了公共参数，这里只需要传入业务参数。以下方法为sdk的model入参方式(model和biz_content同时存在的情况下取biz_content)。
		AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();

		model.setBody("一毛的商品");
		model.setSubject("测试商品一毛"); // 商品标题
		model.setOutTradeNo(orders.getOrderid()); // 商家订单编号
		// model.setTimeoutExpress("525600m"); //超时关闭该订单时间，默认15天
		model.setTotalAmount(orders.getPaymoney().toString()); // 订单总金额
		model.setProductCode("QUICK_MSECURITY_PAY"); // 销售产品码，商家和支付宝签约的产品码，为固定值QUICK_MSECURITY_PAY
		request.setBizModel(model);
		request.setNotifyUrl(PayConstants.ALIPAY_NOTIFY_URL); // 回调地址
		String orderStr = "";
		try {
			// 这里和普通的接口调用不同，使用的是sdkExecute
			AlipayTradeAppPayResponse response = alipayClient
					.sdkExecute(request);
			orderStr = response.getBody();
			logger.info("订单str：" + orderStr);
		} catch (AlipayApiException e) {
			e.printStackTrace();
		}
		return orderStr;
	}

	/*
	 * @Description : 支付宝通知,回调地址
	 * 
	 * @param request
	 * 
	 * @param response
	 * 
	 * @param trade_no 订单号
	 * 
	 * @param price 支付宝支付金额
	 * 
	 * @param trade_status 交易状态
	 * 
	 * @param out_trade_no 第三方单号
	 * 
	 * @param buyer_email 邮箱
	 * 
	 * @param payment_type 支付类型
	 * 
	 * @param subject
	 */
	@RequestMapping(value = "/getAliPayNotify")
	public void getnotify(HttpServletRequest request,
			HttpServletResponse response) {
		logger.info("进入支付宝回调");
		// 获取支付宝GET过来反馈信息
		String reqWay = "";
		if ("GET".equals(request.getMethod())) {
			reqWay = "GET";
		}
		Map<String, String> params = new HashMap<String, String>();
		Map<?, ?> requestParams = request.getParameterMap();
		for (Iterator<?> iter = requestParams.keySet().iterator(); iter
				.hasNext();) {
			String name = (String) iter.next();
			String[] values = (String[]) requestParams.get(name);
			String valueStr = "";
			for (int i = 0; i < values.length; i++) {
				valueStr = (i == values.length - 1) ? valueStr + values[i]
						: valueStr + values[i] + ",";
			}
			// 乱码解决，这段代码在出现乱码时使用。如果mysign和sign不相等也可以使用这段代码转化
			if ("GET".equals(reqWay)) {
				try {
					valueStr = new String(valueStr.getBytes("ISO-8859-1"),
							"utf-8");
				} catch (UnsupportedEncodingException e) {
					logger.info("不支持的编码：" + e.getMessage());
					e.printStackTrace();
				}
			}
			params.put(name, valueStr);
		}

		// 切记alipaypublickey是支付宝的公钥，请去open.alipay.com对应应用下查看。
		// boolean AlipaySignature.rsaCheckV1(Map<String, String> params, String
		// publicKey, String charset, String sign_type)
		String result = "failure";
		try {
			boolean flag = AlipaySignature.rsaCheckV1(params,
					PayConstants.ALIPAY_PUBLIC_KEY, // 这里是支付宝公钥不是应用公钥
					"UTF-8", "RSA2");
			logger.info("接到通知验证结果： " + flag);
			if (flag) {
				if ("TRADE_SUCCESS".equals(params.get("trade_status"))) {
					// 这里写业务逻辑，操作数据库等操作
					String trade_no = request.getParameter("trade_no"); // 支付宝交易号
					String trade_status = request.getParameter("trade_status"); // 支付状态
					String out_trade_no = request.getParameter("out_trade_no"); // 系统订单号
					logger.info("支付宝交易号：" + trade_no + ", 返回状态:" + trade_status
							+ ",订单号  :" + out_trade_no);
					// Orders orders =
					// orderService.selectOrdersInfoByOrderId(out_trade_no);
					Order orders = TempUtils.getOrderByID(out_trade_no);
					orders.setAlipaytradeno(trade_no);
					orders.setEnd_time(System.currentTimeMillis() + "");
					// orders.setStatus("TRADE_SUCCESS");
					orders.setStatus(PayConstants.PAY_STATUS_SUCCESS);
					result = "success";
				}
			}

		} catch (AlipayApiException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}// 验签不通过支付宝会一直回调你的异步回调

		ResponseUtils.renderText(response, result);
	}

	/**
	 * 支付通用接口
	 * 
	 * @param HowToPay
	 * @param orderId
	 * @param forWhat
	 * @param payMoney
	 * @param req
	 * @return
	 */
	@RequestMapping(value = "/queryPayResult")
	public String queryPayResultByOrderId(HttpServletRequest req,
			HttpServletResponse res) {
		String orderId = req.getParameter("orderId");
		logger.info("orderid:" + orderId);
		Order order = TempUtils.getOrderByID(orderId);
		if (order == null) {
			return "order not exist!";
		}
		int status = order.getStatus();
		Result result = new Result();
		if (status == PayConstants.PAY_STATUS_SUCCESS) {
			result.setCode(HttpConstants.HTTP_RESP_SUCCESS);
			result.setMsg("支付成功");
		} else {
			result.setCode(HttpConstants.HTTP_RESP_FAILED);
			result.setMsg("支付失败");
		}

		return GsonUtils.GsonString(result);
	}
}
